home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
051-075
/
scopedisk64
/
microray
/
texture.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
6KB
|
221 lines
/************************************************************************
* *
* Copyright (c) 1988, David B. Wecker *
* All Rights Reserved *
* *
* This file is part of DBW_uRAY *
* *
* DBW_uRAY is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY. No author or distributor accepts *
* responsibility to anyone for the consequences of using it or for *
* whether it serves any particular purpose or works at all, unless *
* he says so in writing. Refer to the DBW_uRAY General Public *
* License for full details. *
* *
* Everyone is granted permission to copy, modify and redistribute *
* DBW_uRAY, but only under the conditions described in the *
* DBW_uRAY General Public License. A copy of this license is *
* supposed to have been given to you along with DBW_uRAY so you *
* can know your rights and responsibilities. It should be in a file *
* named COPYING. Among other things, the copyright notice and this *
* notice must be preserved on all copies. *
************************************************************************
* *
* Authors: *
* DBW - David B. Wecker *
* *
* Versions: *
* V1.0 881023 DBW - First released version *
* V1.1 881110 DBW - Fixed scan coherence code *
* V1.2 881125 DBW - Removed ALL scan coherence code (useless) *
* added "fat" extent boxes *
* *
************************************************************************/
#include "uray.h"
/************************************************************************/
/**************** This module computes textures of objects **************/
/************************************************************************/
/* get the procedure texture */
void gettex(n,intersect,normal,diffuse)
NODE *n;
VEC intersect,normal,diffuse;
{
int i,j,k;
FLTDBL d;
/* start with the default diffuse color */
vcopy(n->att->color,diffuse);
switch (n->att->tex) {
/* no texture */
case 0:
break;
/* checker board, p1 = alternate color, p2 = scale */
case 1:
for (i=j=0; i<3; i++) {
if (n->att->p2[i] > 0.0) {
k = (int)(intersect[i] / n->att->p2[i]);
if (k < 0) j -= k;
else j += k;
}
}
if (j & 1) { vcopy(n->att->p1,diffuse); }
break;
/* random mottled texture, p1 = alternate color */
case 2:
for (i=0; i<3; i++) {
diffuse[i] *= (d=rnd());
diffuse[i] += (1.0-d) * n->att->p1[i];
}
break;
/* blend textures */
case 3: /* X axis blend, p1 = alternate color, p2 = coordinate */
case 4: /* Y axis blend, p1 = alternate color, p2 = coordinate */
case 5: /* Z axis blend, p1 = alternate color, p2 = coordinate */
i = n->att->tex - 3;
if (intersect[i] > n->att->p2[1]) d = n->att->p2[2] - n->att->p2[1];
else d = n->att->p2[0] - n->att->p2[1];
if (d == 0.0) break;
d = (intersect[i] - n->att->p2[1]) / d;
if (d > 1.0) d = 1.0;
if (d < 0.0) d = 0.0;
for (i=0; i<3; i++) {
diffuse[i] *= d;
diffuse[i] += (1.0-d) * n->att->p1[i];
}
break;
}
}
/* return background value (computes sky and ground colors) */
void getamb(frm, dir, retval)
VEC frm, dir, retval;
{
FLTDBL v;
int i;
if (dir[1] < 0.0) {
vcopy(GROUND,retval);
return;
}
if (dir[2] < 0.0) v = 0.0;
else {
v = (1.0 - dir[1]) * dir[2];
if (v > 1.0) v = 1.0;
else v *= v;
}
for (i=0; i<3; i++) {
retval[i] = NEAR[i] * (1.0 - v);
retval[i] += FAR[i] * v;
}
}
/* figure out ripple for current point inside of a wave surface */
void calcripple(point,w,ripple)
VEC point;
int w;
VEC ripple;
{
FLTDBL riprad,damper,tmp;
int i,iriprad;
riprad = 0.0;
for (i=0; i<3; i++) {
ripple[i] = tmp = waves[w].cen[i] - point[i];
riprad += tmp * tmp;
}
/* unit vector pointing away from wave center */
vunit(ripple,ripple);
riprad = sqrt(riprad); /* distance from center to point */
riprad += waves[w].phase * waves[w].length; /* move it */
riprad /= waves[w].length; /* scale half-wave crest to 0..1 */
if (waves[w].damp == 1.0) damper = 1.0;
else damper = pow(waves[w].damp,riprad);
iriprad = (int)riprad;
if (iriprad & 1) {/* negate it */
vscale(-1.0,ripple,ripple);
}
riprad -= (FLTDBL) iriprad; /* just get fraction 0..1 */
riprad -= 0.5; /* scale to -0.5 .. +0.5 */
if (riprad < 0.0) riprad = -riprad; /* absolute value */
riprad = 0.5 - riprad; /* invert */
riprad *= damper;
riprad *= waves[w].amp;
vscale(riprad,ripple,ripple); /* scale bend */
}
/* find surface normal for any object */
FLTDBL findnormal(s,dir,intersect,normal,eflip)
NODE *s;
VEC dir,intersect,normal;
int *eflip;
{
int i;
FLTDBL d;
VEC ripple,fuzzy;
/* first get the standard normal */
switch (s->typ) {
case TYP_S: spherenormal(intersect,s,normal); break;
default: planenormal(s,normal);
}
/* do any desired waves */
if (s->att->wave != -1) { /* don't bother checking if there's no waves*/
if (s->att->wave == -2) { /* fiddle with normal for all ripples */
for (i = 0; i < nwaves; i++) {
calcripple(intersect,i,ripple); /* calculate the wave perturbation */
vadd(ripple,normal,normal); /* add ripple bend to normal */
}
}
/* fiddle with normal for one ripple */
else if (s->att->wave >= 0) {
calcripple(intersect,s->att->wave,ripple); /* calc wave perturbation */
vadd(ripple,normal,normal); /* add ripple bend to normal */
}
vunit(normal,normal); /* make sure it's a unit vector after all that */
}
/* Add any general normal perturbations */
if (s->att->kf > 0.0) {
/* Perturb the normal randomly to produce fuzzy surfaces */
fuzzy[0] = rnd(); /* 0..1 */
fuzzy[1] = rnd();
fuzzy[2] = rnd();
if (rnd() < 0.5) fuzzy[0] = -fuzzy[0];
if (rnd() < 0.5) fuzzy[1] = -fuzzy[1];
if (rnd() < 0.5) fuzzy[2] = -fuzzy[2];
/* 'fuzzy' is now approximately a random unit vector */
vcomb(rnd() * s->att->kf,fuzzy,normal,normal);
vunit(normal,normal); /* make sure it's a unit vector after all that */
}
/* make sure the normal is on the correct side of the surface */
d = -vdot(dir,normal);
*eflip = 0;
if (d < 0.0) {
vscale(-1.0, normal, normal);
*eflip = 1;
d = -d;
}
return d;
}